﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace Odin.Execution.Utils
{
	// Code from http://www.codeproject.com/KB/cs/windowhider.aspx

	/// <summary>

	/// Collection used to enumerate Window Objects

	/// </summary>

	public class Windows : IEnumerable<Window>, IEnumerator<Window>, IDisposable
	{
		/// <summary>

		/// Win32 API Imports

		/// </summary>

		[DllImport("user32.dll")]
		private static extern
			int GetWindowText(int hWnd, StringBuilder title, int size);
		[DllImport("user32.dll")]
		private static extern
			int GetWindowModuleFileName(int hWnd, StringBuilder title, int size);
		[DllImport("user32.dll")]
		private static extern
			int EnumWindows(EnumWindowsProc ewp, int lParam);
		[DllImport("user32.dll")]
		private static extern
			bool IsWindowVisible(int hWnd);

		//delegate used for EnumWindows() callback function

		public delegate bool EnumWindowsProc(int hWnd, int lParam);

		private int m_Position = -1; // holds current index of wndArray, 

		// necessary for IEnumerable


		ArrayList wndArray = new ArrayList(); //array of windows


		//Object's private fields

		private bool m_invisible = false;
		private bool m_notitle = false;

		/// <summary>

		/// Collection Constructor with additional options

		/// </summary>

		/// <param name="Invisible">Include invisible Windows</param>

		/// <param name="Untitled">Include untitled Windows</param>

		public Windows(bool Invisible, bool Untitled)
		{
			m_invisible = Invisible;
			m_notitle = Untitled;

			//Declare a callback delegate for EnumWindows() API call

			EnumWindowsProc ewp = new EnumWindowsProc(EvalWindow);
			//Enumerate all Windows

			EnumWindows(ewp, 0);
		}
		/// <summary>

		/// Collection Constructor

		/// </summary>

		public Windows()
		{
			//Declare a callback delegate for EnumWindows() API call

			EnumWindowsProc ewp = new EnumWindowsProc(EvalWindow);
			//Enumerate all Windows

			EnumWindows(ewp, 0);
		}
		//EnumWindows CALLBACK function

		private bool EvalWindow(int hWnd, int lParam)
		{
			if (m_invisible == false && !IsWindowVisible(hWnd))
				return (true);

			StringBuilder title = new StringBuilder(256);
			StringBuilder module = new StringBuilder(256);

			GetWindowModuleFileName(hWnd, module, 256);
			GetWindowText(hWnd, title, 256);

			if (m_notitle == false && title.Length == 0)
				return (true);

			wndArray.Add(new Window(title.ToString(), (IntPtr)hWnd,
									module.ToString()));

			return (true);
		}

		//implement IEnumerable

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this;
		}

		public IEnumerator<Window> GetEnumerator()
		{
			return this;
		}
		//implement IEnumerator

		public bool MoveNext()
		{
			m_Position++;
			if (m_Position < wndArray.Count)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		public void Reset()
		{
			m_Position = -1;
		}

		object IEnumerator.Current
		{
			get
			{
				return wndArray[m_Position];
			}
		}
		public Window Current
		{
			get
			{
				return wndArray[m_Position] as Window;
			}
		}


		#region IDisposable Members

		public void Dispose()
		{
			
		}

		#endregion
	}
}
